/*******************************************************************************
 * Copyright (c) 2010, 2015 git@git.oschina.net:kaiwill/springstage.git
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 *******************************************************************************/
package com.qinyeit.serviceapp.service.system.impl;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.qinyeit.serviceapp.entity.MaterialCategory;
import com.qinyeit.serviceapp.entity.system.ManagementPermission;
import com.qinyeit.serviceapp.repository.system.ManagementPermissionRepository;
import com.qinyeit.serviceapp.service.system.ManagementPermissionService;
import com.qinyetech.springstage.core.entity.Status;
import com.qinyetech.springstage.core.entity.search.SearchOperator;
import com.qinyetech.springstage.core.entity.search.Searchable;
import com.qinyetech.springstage.core.service.BaseService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/** 
 * ClassName: SystemPermissionServiceImpl <br/> 
 * Function: 权限/菜单<br/>
 * date: 2015年10月6日 上午11:53:07 <br/> 
 * 
 * @author wuqing 
 * @version  
 * @since JDK 1.7 
 */
@Service
@Transactional
public class ManagementPermissionServiceImpl extends BaseService<ManagementPermission, Long> implements ManagementPermissionService {

	@Autowired
	private ManagementPermissionRepository systemPermissionRepository;


	@Override
	public List<ManagementPermission> allPermission() {
		return systemPermissionRepository.findByParentIsNull();
	}

	@Override
	public Set<ManagementPermission> findPermissionBySystemAccountId(Long id) {
		//TODO implemetn it
		return null;
	}
	@Override
	public boolean distroyAble(ManagementPermission managementPermission) {
		if(managementPermission.isDeleteAble()){
			//检查是否被使用
			if(systemPermissionRepository.usedCount(managementPermission.getId())<=0){
				return true; //没有被使用过
			}

		}
		return false;
	}


	/**
	 * 根据账户主键获取所有权限
	 * @return 权限字符串 列表
	 */
//	@Override
//	public Set<ManagementPermission> findPermissionBySystemAccountId(Long id) {
//		Set<ManagementPermission> permissionSet;
//		Cache cache=cacheManager.getCache(CacheConstants.CACHE_SYSTEM_ACCOUNT_PERMISSION);
//		if(cache!=null){
//			permissionSet=cache.get(CacheConstants.CACHE_KEY_SYSTEM_ACCOUNT_ID_PERMISSION+id, Set.class);
//			if(CollectionUtils.isNotEmpty(permissionSet)){
//				return permissionSet;
//			}
//		}
//		permissionSet=systemPermissionRepository.findPermission(id);
//		if(cache!=null && CollectionUtils.isNotEmpty(permissionSet)){
//			cache.put(CacheConstants.CACHE_KEY_SYSTEM_ACCOUNT_ID_PERMISSION+id,permissionSet);
//		}
//		return permissionSet;
//	}


	@Cacheable(value = "permission")
	@Override
	public List<ManagementPermission> findAll() {
		return super.findAll();
	}


	/**
	 * 只用于初始化权限数据
	 * @param managementPermissions 从系统读取的权限
	 * @return
	 */
	@Transactional
	public void init(Set<ManagementPermission> managementPermissions){
		//从数据库中读取所有权限字符串
		final Set<String> permissionCodesIndb=systemPermissionRepository.findAllPermissions();

		if(CollectionUtils.isEmpty(managementPermissions)){
			return;
		}
		Set<String> permissionCodesFromRead=Sets.newHashSet();
		managementPermissions.forEach(item->{
			permissionCodesFromRead.add(item.getCode());
			if(!permissionCodesIndb.contains(item.getCode())){ //数据库中不包含
				this.save(item);//保存到数据库
			}
		});
		//数据库中存在，但最新读取到的没有,则做逻辑删除
		Set<String> deleting=Sets.difference(permissionCodesIndb,permissionCodesFromRead);
		if(CollectionUtils.isNotEmpty(deleting)){
			log.warn("数据库中需要删除旧的ManagementPermission权限信息:"+deleting+",初始化程序会将is_deleted字段标记为true,请手工删除权限信息");
			deleting.forEach(item->logicDeleteByCode(item));
		}
	}

	private void logicDeleteByCode(String code){
		Searchable searchable=Searchable.newSearchable();
		searchable.addSearchFilter("code", SearchOperator.eq,code);
		ManagementPermission managementPermission= findOne(searchable);
		if(managementPermission!=null){
			managementPermission.setDeleted(true);
			update(managementPermission);
		}
	}

	/**
	 * 构建菜单
	 * @return
	 */
	public String buildCurrentAccountMenuHtml(String contextPath){
//		Searchable searchable=Searchable.newSearchable();
//		searchable.addSearchFilter("status",SearchOperator.eq,0);
//		searchable.addSearchFilter("type",SearchOperator.ne, ManagementPermission.Type.Button);
//		searchable.addSort(Sort.Direction.ASC,"displayOrder");
//		List<ManagementPermission> managementPermissionList=findWithSort(searchable);
//
//		//过滤权限
//		List<ManagementPermission> filtedManagementPermissions=managementPermissionList.stream().filter(item->{
//			if(item.getType()== ManagementPermission.Type.Button) return false;
//			if(item.getType()== ManagementPermission.Type.Menu ){ //如果是菜单
//				if(StringUtils.isBlank(item.getCode())){
//					return false;
//				}
//				return SecurityUtils.getSubject().isPermitted(item.getCode());
//			}
//			return true; //目录将会被保留下来
//		}).collect(Collectors.toList());
//
//		List<ManagementPermission> menu=buildMenu(filtedManagementPermissions);
//		final StringBuilder sb=new StringBuilder();
//		menu.forEach(item->createMenuHtml(item,contextPath,sb));
//		return sb.toString();
		return "";
	}

	/**
	 * 组织树结构
	 * @param platManagementPermissions
	 * @return
	 *//*
	private List<ManagementPermission> buildMenu(List<ManagementPermission> platManagementPermissions){
		Map<Long,ManagementPermission> map= Maps.newHashMap();
		List<ManagementPermission> result= Lists.newArrayList();
		platManagementPermissions.forEach(item->map.put(item.getId(),item));
		platManagementPermissions.forEach(item->{
				if(item.getParent()==null){
					result.add(item);
				}else{
					Long parentId=item.getParent().getId();
					map.get(parentId).getChildMenu().add(item);
				}
		});
		return result;
	}*/

	/**
	 * 创建菜单HTML
	 * @param managementPermission
	 * @param contextPath
	 * @return
	 */
	private void createMenuHtml(ManagementPermission managementPermission,String contextPath,StringBuilder sb){
		if(managementPermission.getType()== ManagementPermission.Type.Menu){
			sb.append(createMenuItemHtml(managementPermission,contextPath));
			return;
		}
		if(managementPermission.getType()== ManagementPermission.Type.Directory && managementPermission.getChildMenu().size()>0){ //目录,并且有子菜单
			StringBuilder sbMenuHtml=new StringBuilder("<li>");
			String tagA="<a href=\"#\">%s<span class=\"nav-label\">%s</span><span class=\"fa arrow\"></span></a>";
			String s0=StringUtils.isNotBlank(managementPermission.getIcon())?" <i class=\""+managementPermission.getIcon()+"\"></i>":"";
			String s1=managementPermission.getName();
			sbMenuHtml.append(String.format(tagA,s0,s1));
			sbMenuHtml.append(" <ul class=\"nav nav-second-level collapse\">");
			for (ManagementPermission permission : managementPermission.getChildMenu()) {
				createMenuHtml(permission,contextPath,sbMenuHtml);
			}
			sbMenuHtml.append("</ul></li>");
			//判断是否有子菜单
			String strMenuHtml=sbMenuHtml.toString();
			if(strMenuHtml.contains("J_menuItem")){
				sb.append(strMenuHtml);
			}
		}
	}



	/**
	 *  <li>
	 <a class="J_menuItem" href="${ctx}/management/vipPointRecords">
	 <i class="fa fa-diamond"></i> <span class="nav-label">代码生成器测试</span></a>
	 </li>
	 *
	 * 创建菜单项 HTML
	 * @param managementPermission
	 * @return
	 */
	private String createMenuItemHtml(ManagementPermission managementPermission,String contextPath){
			String menuItemTpl="<li><a class=\"J_menuItem\" href=\"%s%s\">%s<span class=\"nav-label\">%s</span></a></li>";
			String s0=contextPath;
			String s1=managementPermission.getActionUrl();
			String s2="";
			if(StringUtils.isNotBlank(managementPermission.getIcon())){
				s2="<i class=\""+managementPermission.getIcon()+"\"></i>";
			}
			String s3=managementPermission.getName();
			return String.format(menuItemTpl,s0,s1,s2,s3);
	}

	@Override
	public void statusSwitch(Long id, Status status) {
		systemPermissionRepository.statusSwitch(status,id);
	}

	@Override
	public List<ManagementPermission> getPermission() {
		Searchable searchable=Searchable.newSearchable();
		searchable.addSearchParam("deleted_eq",false);
		List<ManagementPermission> models = findWithSort(searchable);//查询所有
//		return models;
		return associateList(models, 0L);
	}

	/**
	 *
	 * associateList:处理关联 <br>
	 *
	 * @author wuqing
	 * @param models
	 * 返回根节点集合
	 * @since JDK 1.7
	 */
	private List<ManagementPermission> associateList(List<ManagementPermission> models, Long id){
		List<ManagementPermission> result=Lists.newArrayList();
		if(models!=null && models.size()>0){
			for (int i=0;i<models.size();i++) {
				ManagementPermission model = models.get(i);
				if(id.equals(model.getParentId())){
					model.setChildren(associateList(models, model.getId()));
					result.add(model);
				}
			}
		}
		return result;
	}



}
